﻿using System;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.Serialization;
using Newtonsoft.Json;

namespace HproseRpcTester.Utils
{
    /// <summary>
    /// 通用扩展类
    /// </summary>
    public static class CommonExtension
    {
        #region 枚举操作
        /// <summary>
        /// 获取该枚举值的EnumMember特性的value值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="src"></param>
        /// <returns></returns>
        public static string GetEnumMemberAttributeValue<T>(this T src) where T : Enum
        {
            //string value = src.ToString();
            //FieldInfo field = typeof(T).GetField(value);
            //object[] objs = field.GetCustomAttributes(typeof(EnumMemberAttribute), false);
            //if (!(objs == null || objs.Length == 0))
            //    value = ((EnumMemberAttribute)objs[0]).Value;
            //return value;
            return src.GetAttributeDefaultValue<string, EnumMemberAttribute, T>();
        }
        /// <summary>
        /// 不区分字符串大小写，根据枚举名称获取枚举，默认返回最后一个枚举
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="src"></param>
        /// <param name="str"></param>
        /// <returns></returns>
        public static object GetEnumByValueCaseSensitiveFree(this Type type, string str)
        {
            object result = null;

            foreach (var t in Enum.GetValues(type))
            {

                if (t.ToString().ToUpper() == str.ToUpper())
                {
                    result = t;
                    break;
                }
                result = t;
            }
            return result;
        }
        /// <summary>
        /// 获取该枚举值的Description特性的Description值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="src"></param>
        /// <returns></returns>
        public static string GetDescription<T>(this T src) where T : Enum
        {
            try
            {
                return src.GetAttributeDefaultValue<string, DescriptionAttribute, T>();
            }
            catch { return "<空>"; }
        }

        public static TResult GetAttributeDefaultValue<TResult, AttributeType, EnumType>(this EnumType src)
            where EnumType : Enum
            where AttributeType : Attribute
        {
            TResult result = default;
            try
            {
                string value = src.ToString();
                FieldInfo field = typeof(EnumType).GetField(value);
                var property = typeof(AttributeType).GetProperties();
                object[] objs = field.GetCustomAttributes(typeof(AttributeType), false);
                if (!(objs == null || objs.Length == 0))
                    if (property.Length > 0) 
                        result = (TResult)property[0].GetValue(((AttributeType)objs[0]));
                return result;
            }
            catch { return result; }
        }
        #endregion

        /// <summary>
        /// 是否是奇数
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static bool IsOdd(this int n)
        {
            return Convert.ToBoolean(n & 1);
        }

        #region 数组操作
        public static int LastIndex(this float[] src, Func<float, bool> fun)
        {
            if (src == null) return -1;
            if (src.Length == 0) return -1;
            for (int i = src.Length - 1; i > -1; i--)
                if (fun(src[i])) return i;
            return -1;
        }

        public static int FirstIndex(this float[] src, Func<float, bool> fun)
        {
            if (src == null) return -1;
            if (src.Length == 0) return -1;
            for (int i = 0; i < src.Length; i++)
                if (fun(src[i])) return i;
            return -1;
        } 
        #endregion

        #region Json
        public static string ToJson<T>(this T data) => JsonConvert.SerializeObject(data);

        public static T ToData<T>(this string json) => JsonConvert.DeserializeObject<T>(json);
        #endregion
    }
}
